home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 37
/
Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso
/
Aminet
/
biz
/
dopus
/
DOpus414JRsrc.lha
/
DirectoryOpus4
/
DOpus_Print
/
doprint.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-01-29
|
21KB
|
571 lines
/*
Directory Opus 4
Original GPL release version 4.12
Copyright 1993-2000 Jonathan Potter
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
All users of Directory Opus 4 (including versions distributed
under the GPL) are entitled to upgrade to the latest version of
Directory Opus version 5 at a reduced price. Please see
http://www.gpsoft.com.au for more information.
The release of Directory Opus 4 under the GPL in NO WAY affects
the existing commercial status of Directory Opus 5.
*/
#include "print.h"
#include <proto/powerpacker.h>
struct PrintHandle {
int filehandle;
struct MsgPort *port;
struct IOStdReq *ioreq;
char *filename;
int current_line;
int current_page;
int paper_lines;
int paper_width;
int paper_height;
char buffer[1024];
char datebuf[12];
char fileoutput;
struct RequesterBase *reqbase;
struct RastPort *req_rp;
int total_pos;
int filesize;
int progress_y;
int req_width;
};
int do_header_footer(struct PrintHandle *,PrintData *,int);
int do_printstyle(struct PrintHandle *,int,int);
int print_str(struct PrintHandle *,char *,int);
int printer_command(struct RequesterBase *,struct PrintHandle *,char *);
int check_print_abort(struct RequesterBase *);
void show_progress(struct PrintHandle *);
void print_status(struct PrintHandle *handle,char *text,int y);
char
*esc_styles[]={
"\x1b[0m", /* STYLE_NORMAL */
"\x1b[1m", /* STYLE_BOLD */
"\x1b[3m", /* STYLE_ITALICS */
"\x1b[4m", /* STYLE_UNDERLINED */
"\x1b[4\"z", /* STYLE_DOUBLESTRIKE */
"\x1b[6\"z"}; /* STYLE_SHADOW */
printfile(reqbase,filename,printdata,requester)
struct RequesterBase *reqbase;
char *filename;
PrintData *printdata;
struct Requester *requester;
{
int fileh=0,a,lastspace=-1,margin,filesize,ret=0;
int buffersize,size,pos=0,bufpos=0;
char *buffer=NULL,*linebuffer,*marginbuf;
struct PrintHandle *handle;
struct DOpusRemember *memkey=NULL;
struct DOpusDateTime *datetime;
struct TextFont *font;
FOREVER {
if (CheckExist(filename,&filesize)<0) break;
if (!(check_error(reqbase,string_table[STR_UNABLE_TO_OPEN_FILE],0)))
return(0);
}
if (!(datetime=LAllocRemember(&memkey,sizeof(struct DOpusDateTime),MEMF_CLEAR)) ||
!(handle=LAllocRemember(&memkey,sizeof(struct PrintHandle),MEMF_CLEAR))) {
LFreeRemember(&memkey);
return(0);
}
handle->paper_lines=(printdata->bottom_margin-printdata->top_margin)+1;
handle->paper_height=handle->paper_lines;
if (printdata->headfoot[FOOTER].headfoot_flags) handle->paper_lines-=2;
handle->paper_width=(printdata->right_margin-printdata->left_margin)+1;
handle->filename=BaseName(filename);
handle->reqbase=reqbase;
if ((margin=printdata->left_margin-1)>0) {
if (!(marginbuf=LAllocRemember(&memkey,margin+1,MEMF_CLEAR)))
goto ENDPRINT;
for (a=0;a<margin;a++) marginbuf[a]=' ';
}
if (!(linebuffer=LAllocRemember(&memkey,(handle->paper_width*2)+4,MEMF_CLEAR)))
goto ENDPRINT;
if (Request(requester,reqbase->rb_window)) {
font=reqbase->rb_window->RPort->Font;
handle->req_rp=requester->ReqLayer->rp;
handle->req_width=requester->Width;
Do3DBox(handle->req_rp,2,1,
requester->Width-4,requester->Height-2,
reqbase->rb_shine,reqbase->rb_shadow);
SetAPen(handle->req_rp,reqbase->rb_fg);
SetBPen(handle->req_rp,reqbase->rb_bg);
SetDrMd(handle->req_rp,JAM2);
SetFont(handle->req_rp,font);
handle->progress_y=font->tf_YSize*3;
print_status(handle,
(printdata->print_flags&PRINTFLAG_FILE && printdata->output_file[0])?
string_table[STR_CREATING_FILE]:
string_table[STR_OPENING_PRINTER],
handle->progress_y);
}
if (printdata->print_flags&PRINTFLAG_FILE && printdata->output_file[0]) {
FOREVER {
if ((handle->filehandle=Open(printdata->output_file,
(a=(CheckExist(printdata->output_file,NULL))?MODE_READWRITE:MODE_NEWFILE)))) {
if (a==MODE_READWRITE) Seek(handle->filehandle,0,OFFSET_END);
handle->fileoutput=1;
break;
}
if (!(check_error(reqbase,string_table[STR_UNABLE_TO_OPEN_OUTPUT],0)))
goto ENDPRINT;
}
}
else {
struct Preferences *prefs;
if (!(handle->port=LCreatePort(NULL,0)) ||
!(handle->ioreq=(struct IOStdReq *)LCreateExtIO(handle->port,sizeof(struct IOStdReq))))
goto ENDPRINT;
FOREVER {
if (!(OpenDevice("printer.device",0,(struct IORequest *)handle->ioreq,0))) break;
if (!(check_error(reqbase,string_table[STR_UNABLE_TO_OPEN_PRINTER],0))) {
LDeleteExtIO((struct IORequest *)handle->ioreq);
handle->ioreq=NULL;
goto ENDPRINT;
}
}
prefs=&(((struct PrinterData *)handle->ioreq->io_Device)->pd_Preferences);
prefs->PrintLeftMargin=1;
prefs->PrintRightMargin=printdata->right_margin;
prefs->PaperLength=printdata->bottom_margin+2;
if (printdata->print_pitch==PITCH_PICA) prefs->PrintPitch=PICA;
else if (printdata->print_pitch==PITCH_FINE) prefs->PrintPitch=FINE;
else if (printdata->print_pitch==PITCH_ELITE) prefs->PrintPitch=ELITE;
if (printdata->text_quality==QUALITY_DRAFT) prefs->PrintQuality=DRAFT;
else prefs->PrintQuality=LETTER;
if (!(printer_command(reqbase,handle,"\033#1"))) goto ENDPRINT;
}
if (handle->req_rp) {
SetAPen(handle->req_rp,reqbase->rb_bg);
RectFill(handle->req_rp,2,1,
requester->Width-3,requester->Height-2);
print_status(handle,string_table[STR_LOADING_FILE],handle->progress_y);
}
if (PPBase) {
FOREVER {
if ((a = ppLoadData(filename,DECR_POINTER,MEMF_CLEAR,(UBYTE **)&buffer,&buffersize,NULL))==PP_PASSERR) {
if (!(check_error(reqbase,string_table[STR_INCORRECT_PASSWORD],0)))
goto ENDPRINT;
}
else break;
}
size=buffersize;
filesize=buffersize;
}
if (!buffer) {
buffersize=filesize;
while (!(buffer=AllocMem(buffersize,MEMF_CLEAR))) {
buffersize/=2;
if (buffersize==0) goto ENDPRINT;
}
if (!(fileh=Open(filename,MODE_OLDFILE))) goto ENDPRINT;
size=Read(fileh,buffer,buffersize);
}
handle->filesize=filesize;
if (handle->req_rp) {
print_status(handle,
string_table[STR_PRINTING_FILE],
font->tf_YSize);
print_status(handle,
string_table[STR_PRESS_ESCAPE],
(font->tf_YSize*5));
show_progress(handle);
}
DateStamp(&datetime->dat_Stamp);
datetime->dat_Format=FORMAT_DOS;
datetime->dat_StrDate=handle->datebuf;
StampToStr(datetime);
FOREVER {
if (bufpos>=size && (!fileh || (size=Read(fileh,buffer,buffersize))<1)) {
if (pos>0) {
if ((marginbuf && !(print_str(handle,marginbuf,-1))) ||
!(print_str(handle,linebuffer,pos))) goto ENDPRINT;
}
if (handle->current_line<=handle->paper_lines) {
if (handle->current_line==0) {
for (a=1;a<printdata->top_margin;a++)
if (!(print_str(handle,"\n",1))) goto ENDPRINT;
++handle->current_page;
}
if (printdata->headfoot[FOOTER].headfoot_flags) {
for (;handle->current_line<handle->paper_lines;handle->current_line++)
if (!(print_str(handle,"\n",1))) goto ENDPRINT;
if (!(do_header_footer(handle,printdata,FOOTER)))
break;
}
}
if (handle->current_line>0 &&
printdata->print_flags&PRINTFLAG_EJECT &&
!(print_str(handle,"\f",1))) break;
break;
}
bufpos=0;
while (bufpos<size) {
if (check_print_abort(reqbase)) goto ENDPRINT;
if (handle->current_line<handle->paper_lines) {
if (handle->current_line==0) {
for (a=1;a<printdata->top_margin;a++)
if (!(print_str(handle,"\n",1))) goto ENDPRINT;
++handle->current_page;
}
if (handle->current_line==0 &&
printdata->headfoot[HEADER].headfoot_flags) {
if (!(do_header_footer(handle,printdata,HEADER))) goto ENDPRINT;
handle->current_line+=2;
}
else {
while (bufpos<size && handle->current_line<handle->paper_lines) {
if (check_print_abort(reqbase)) goto ENDPRINT;
switch (buffer[bufpos]) {
/* Tab character; pad buffer with spaces to next tab stop */
case '\t':
if ((pos%printdata->tab_size)==0) a=printdata->tab_size;
else a=(((pos/printdata->tab_size)+1)*printdata->tab_size)-pos;
while (pos<=handle->paper_width && (a--))
linebuffer[(pos++)]=' ';
lastspace=pos-1;
break;
/* Form feed */
case '\f':
if (pos>0) {
if (marginbuf && !(print_str(handle,marginbuf,margin)))
goto ENDPRINT;
if (!(print_str(handle,linebuffer,pos))) goto ENDPRINT;
}
if (printdata->headfoot[FOOTER].headfoot_flags) {
for (;handle->current_line<handle->paper_lines;handle->current_line++)
if (!(print_str(handle,"\n",1))) goto ENDPRINT;
}
else {
handle->current_line=0;
if (!(print_str(handle,"\f",1))) goto ENDPRINT;
}
lastspace=-1; pos=0;
show_progress(handle);
break;
/* New line */
case '\n':
/* Only store newline character in buffer if we are not
on the last line of the page */
if (handle->current_line<handle->paper_height-1 || handle->fileoutput)
linebuffer[pos++]='\n';
if (marginbuf && !(print_str(handle,marginbuf,margin)))
goto ENDPRINT;
if (!(print_str(handle,linebuffer,pos))) goto ENDPRINT;
lastspace=-1; pos=0; ++handle->current_line;
show_progress(handle);
break;
default:
if (isspace(buffer[bufpos])) lastspace=pos;
else if (ispunct(buffer[bufpos])) {
if (lastspace==-1 || pos>lastspace+8) lastspace=pos;
}
linebuffer[pos++]=buffer[bufpos];
if (pos>handle->paper_width) {
if (marginbuf && !(print_str(handle,marginbuf,margin)))
goto ENDPRINT;
if (lastspace>0 && lastspace<pos) {
a=lastspace+1;
if (!(print_str(handle,linebuffer,a-(isspace(linebuffer[lastspace])?1:0))))
goto ENDPRINT;
pos-=a;
if (pos>0) CopyMem(&linebuffer[a],linebuffer,pos);
}
else {
if (!(print_str(handle,linebuffer,handle->paper_width)))
goto ENDPRINT;
linebuffer[0]=linebuffer[handle->paper_width];
pos=1;
}
if (handle->current_line<handle->paper_height-1 || handle->fileoutput) {
if (!(print_str(handle,"\n",1))) goto ENDPRINT;
}
if (pos<0) {
pos=0;
show_progress(handle);
}
lastspace=-1;
for (a=0;a<pos;a++) {
if (isspace(linebuffer[a])) lastspace=a;
else if (ispunct(linebuffer[a])) {
if (lastspace==-1 || pos>lastspace+8) lastspace=a;
}
}
++handle->current_line;
}
break;
}
++bufpos;
++handle->total_pos;
}
}
}
else {
if (!(do_header_footer(handle,printdata,FOOTER))) goto ENDPRINT;
handle->current_line=0;
if (!(print_str(handle,"\f",1))) goto ENDPRINT;
}
}
}
ret=1;
ENDPRINT:
if (buffer) FreeMem(buffer,buffersize);
if (fileh) Close(fileh);
if (handle->filehandle) Close(handle->filehandle);
if (handle->ioreq) {
CloseDevice((struct IORequest *)handle->ioreq);
LDeleteExtIO((struct IORequest *)handle->ioreq);
}
if (handle->port) LDeletePort(handle->port);
if (handle->req_rp) EndRequest(requester,reqbase->rb_window);
LFreeRemember(&memkey);
return(ret);
}
do_header_footer(handle,printdata,type)
struct PrintHandle *handle;
PrintData *printdata;
int type;
{
int a,b;
int leftoffset;
int len;
if (printdata->headfoot[type].headfoot_flags) {
leftoffset=printdata->left_margin-1;
if (!(do_printstyle(handle,printdata->headfoot[type].text_style,1)))
return(0);
for (a=0;a<sizeof(handle->buffer);a++) handle->buffer[a]=' ';
if (printdata->headfoot[type].headfoot_flags&HEADFOOTFLAG_DATE)
CopyMem(handle->datebuf,&handle->buffer[leftoffset+1],9);
if (printdata->headfoot[type].headfoot_flags&HEADFOOTFLAG_TITLE) {
char titlebuf[40];
if (printdata->headfoot[type].headfoot_title[0])
strcpy(titlebuf,printdata->headfoot[type].headfoot_title);
else strcpy(titlebuf,handle->filename);
if ((a=strlen(titlebuf))>handle->paper_width) {
a=handle->paper_width;
b=0;
}
else b=(handle->paper_width-a)/2;
b+=leftoffset;
CopyMem(titlebuf,&handle->buffer[b],a);
}
if (printdata->headfoot[type].headfoot_flags&HEADFOOTFLAG_PAGE) {
char pagebuf[20];
lsprintf(pagebuf,"%s %ld",string_table[STR_PAGE],handle->current_page);
a=leftoffset+(handle->paper_width-strlen(pagebuf)-1);
CopyMem(pagebuf,&handle->buffer[a],strlen(pagebuf));
}
if (type==FOOTER && !(print_str(handle,"\n",-1))) return(0);
len=leftoffset+handle->paper_width;
if (type==HEADER || handle->fileoutput) {
handle->buffer[leftoffset+handle->paper_width]='\n';
len+=1;
}
if (!(print_str(handle,handle->buffer,len))) return(0);
if (type==HEADER && !(print_str(handle,"\n",-1))) return(0);
if (!(do_printstyle(handle,printdata->headfoot[type].text_style,0)))
return(0);
}
return(1);
}
do_printstyle(handle,style,turnon)
struct PrintHandle *handle;
int style,turnon;
{
int a=1;
if (handle->ioreq) {
if (turnon) a=print_str(handle,esc_styles[style],-1);
else {
if ((a=print_str(handle,esc_styles[0],-1))) {
if (style==STYLE_DOUBLESTRIKE)
a=print_str(handle,DOUBLESTRIKE_OFF,-1);
else if (style==STYLE_SHADOW)
a=print_str(handle,SHADOW_OFF,-1);
}
}
}
return(a);
}
print_str(handle,string,stlen)
struct PrintHandle *handle;
char *string;
int stlen;
{
int len,success,seek;
if ((len=stlen)==-1) {
if ((len=strlen(string))>handle->paper_width)
len=handle->paper_width;
}
if (len<1) return(1);
FOREVER {
seek=0;
if (handle->filehandle) {
success=((seek=Write(handle->filehandle,string,len))==len);
}
else if (handle->ioreq) {
handle->ioreq->io_Length=len;
handle->ioreq->io_Data=(APTR)string;
handle->ioreq->io_Command=CMD_WRITE;
success=(!(DoIO((struct IORequest *)handle->ioreq)));
}
else return(0);
if (success) return(1);
if (!(check_error(handle->reqbase,string_table[STR_PRINT_ERROR],0))) return(0);
if (seek>0) Seek(handle->filehandle,-seek,0);
}
}
printer_command(reqbase,handle,command)
struct RequesterBase *reqbase;
struct PrintHandle *handle;
char *command;
{
handle->ioreq->io_Length=-1;
handle->ioreq->io_Data=(APTR)command;
handle->ioreq->io_Command=CMD_WRITE;
FOREVER {
if (!(DoIO((struct IORequest *)handle->ioreq))) break;
if (!(check_error(reqbase,string_table[STR_UNABLE_TO_OPEN_PRINTER],0)))
return(0);
}
return(1);
}
check_print_abort(reqbase)
struct RequesterBase *reqbase;
{
struct IntuiMessage *msg;
int abort=0;
while (msg=(struct IntuiMessage *)GetMsg(reqbase->rb_window->UserPort)) {
if (msg->Class==IDCMP_VANILLAKEY && msg->Code==0x1b) {
if (check_error(reqbase,string_table[STR_REALLY_ABORT],1))
abort=1;
}
ReplyMsg((struct Message *)msg);
}
return(abort);
}
void show_progress(handle)
struct PrintHandle *handle;
{
float percent;
char buf[20];
if (!handle->total_pos || !handle->filesize) percent=0;
else percent=((float)((float)handle->total_pos/(float)handle->filesize))*100;
lsprintf(buf,"%3ld%% %s ",(int)percent,string_table[STR_COMPLETE]);
print_status(handle,buf,handle->progress_y);
}
void print_status(handle,text,y)
struct PrintHandle *handle;
char *text;
int y;
{
int x;
struct TextFont *font;
struct RequesterBase *reqbase;
reqbase=handle->reqbase;
font=handle->req_rp->Font;
x=(handle->req_width-((strlen(text))*font->tf_XSize))/2;
if (x>1) {
SetAPen(handle->req_rp,reqbase->rb_bg);
RectFill(handle->req_rp,
2,y,
x,y+font->tf_YSize);
}
SetAPen(handle->req_rp,reqbase->rb_fg);
UScoreText(handle->req_rp,text,x,y+font->tf_Baseline,-1);
if (handle->req_rp->cp_x<handle->req_width-2) {
SetAPen(handle->req_rp,reqbase->rb_bg);
RectFill(handle->req_rp,
handle->req_rp->cp_x,y,
handle->req_width-3,y+font->tf_YSize);
}
SetAPen(handle->req_rp,reqbase->rb_fg);
}